#pragma once

#include <AVUIDependencyObject.h>
#include <AVUIStyleStructures.h>

namespace AVUI {

class TriggerActionCollection;
class SetterBaseCollection;
class TriggerAction;
class HybridDictionary;
typedef TArray< TRefCountedPtr<HybridDictionary> > HybridDictionaryArray;

/// <summary>Represents the base class for specifying a conditional value within a <see cref="T:System.Windows.Style" /> object. </summary>
class TriggerBase : public DependencyObject
{
public:
    DECLARE_ELEMENT(TriggerBase, DependencyObject);

#pragma region Public Properties

    /// <summary>Gets a collection of <see cref="T:System.Windows.TriggerAction" /> objects to apply when the trigger object becomes active. This property does not apply to the <see cref="T:System.Windows.EventTrigger" /> class.</summary>
    /// <returns>The default value is null.</returns>
    TriggerActionCollection* get_EnterActions();
    DECLARE_READONLY_PROPERTY(EnterActions, TriggerActionCollection, false);

    /// <summary>Gets a collection of <see cref="T:System.Windows.TriggerAction" /> objects to apply when the trigger object becomes inactive. This property does not apply to the <see cref="T:System.Windows.EventTrigger" /> class.</summary>
    /// <returns>The default value is null.</returns>
    TriggerActionCollection* get_ExitActions();
    DECLARE_READONLY_PROPERTY(ExitActions, TriggerActionCollection, false);

#pragma endregion Public Properties

public:

#pragma region Internal Methods

    TriggerBase();
    virtual void AddInheritanceContext(DependencyObject* pContext, DependencyProperty* pProperty) AVUI_OVERRIDE;
    void AddToPropertyValues(String* pChildName, DependencyProperty* pDP, Object* pValue, PropertyValueType::Enum valueType);
    void EstablishLayer();
    virtual bool GetCurrentState(DependencyObject* pContainer, UncommonField<HybridDictionaryArray>* pDataField) { return false; }
    void ProcessParametersContainer(DependencyProperty* pDP);
    TRefCountedPtr<String> ProcessParametersVisualTreeChild(DependencyProperty* pDP, String* pTarget);
    void ProcessSettersCollection(SetterBaseCollection* pSetters);
    virtual void RemoveInheritanceContext(DependencyObject* pContext, DependencyProperty* pProperty) AVUI_OVERRIDE;
    virtual void Seal() AVUI_OVERRIDE;

#pragma endregion Internal Methods

#pragma region Internal Properties

    bool get_ExecuteEnterActionsOnApply() { return true; }
    bool get_ExecuteExitActionsOnApply() { return false; }
    bool get_HasEnterActions();
    bool get_HasExitActions();
    virtual bool get_HasMultipleInheritanceContexts() AVUI_OVERRIDE { return m_hasMultipleInheritanceContexts; }
    DependencyObject* get_InheritanceContext() AVUI_OVERRIDE { return m_pInheritanceContext; }
    int get_Layer() { return m_globalLayerRank; }
    TArrayPtr<TriggerCondition> get_TriggerConditions() { return m_triggerConditions; }
    void set_TriggerConditions(TArrayPtr<TriggerCondition> pValue) { m_triggerConditions = pValue; }

#pragma endregion Internal Properties

#pragma region Internal Fields

    ItemStructList<PropertyValue> PropertyValues;

#pragma endregion Internal Fields

private:

#pragma region Private Fields

    TRefCountedPtr<TriggerActionCollection> m_pEnterActions;
    TRefCountedPtr<TriggerActionCollection> m_pExitActions;
    int m_globalLayerRank;
    bool m_hasMultipleInheritanceContexts;
    TWeakPtr<DependencyObject> m_pInheritanceContext;
    static int m_nextGlobalLayerRank;
    TArrayPtr<TriggerCondition> m_triggerConditions;

#pragma endregion Private Fields

};

typedef TRefCountedPtr<TriggerBase> TriggerBasePtr;


}; // namespace AVUI
